#include "MainWindow.h"
#include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // Alterar o zoom e as cores ao iniciar:
    ui->glWidget->setZoom(5.5);//zoom padrăo: 5.5

    // Checar qual método está marcado:
    this->metodo_fecho = 0;
    if(ui->None->isChecked())        metodo_fecho = 0;
    else if(ui->Jarvis->isChecked()) metodo_fecho = 1;
    else if(ui->Graham->isChecked()) metodo_fecho = 2;
    cout<<"Metodo marcado: "<<metodo_fecho<<endl;

    this->pasta.setPath("Inputs");
    ui->ListaArquivos->addItems(listarArquivos());
}

MainWindow::~MainWindow()
{
    delete ui;
}

QStringList MainWindow::listarArquivos()
{
    return(pasta.entryList(QStringList("*.in"),QDir::Files,QDir::Name));
}

void MainWindow::abrirArquivo(QString nome)
{
    // Use a barra "/" que o Qt se encarrega de trocar pela barra invertida dependendo do S.O.:
    QString arquivo = pasta.absolutePath()+"/"+nome;

    cout<<"abrirArquivo.nome: "<<arquivo.toStdString()<<endl;

    // Resetando o titulo e os grupos lidos:
    titulo(QString());
    grupos_lidos.clear();

    // Fazer a leitura do arquivo:
    if (!fh.leitura(arquivo))
    {
        cout<<"\nERRO: arquivo nao foi encontrado ou nao pode ser aberto:\n("<<arquivo.toStdString()<<")"<<endl;
        return;
    }

    // Setando o titulo e os grupos lidos:
    titulo(nome);
    grupos_lidos = fh.getGrupos();

    cout<<"**************************"<<endl;
    cout<<"* Dados lidos do arquivo *"<<endl;
    cout<<"**************************"<<endl;
    foreach(const Grupo &g,grupos_lidos)
    {
        g.imprimir();
        cout<<endl;
    }

    cout<<"* Foram lidos "<<fh.getEstatisticas().first<<" grupo(s) e "<<fh.getEstatisticas().second<<" ponto(s)."<<endl;

    // Colocando os pontos lidos na lista da "glWidget":
    ui->glWidget->objects_Esvaziar();
    ui->glWidget->addDrawble(new poligono(grupos_lidos));
    ui->glWidget->updateGL();

    cout<<"glWidget.quantObjects: "<<ui->glWidget->objects_quantidade()<<endl;
}

void MainWindow::titulo(QString t)
{
    if (t.isEmpty()) setWindowTitle("Fecho Convexo");
    else setWindowTitle("Fecho Convexo: "+t);
}

void MainWindow::rotate()
{
    cout<<"AVISO: rotate() esta desativada!"<<endl;
//    ui->glWidget->rotateX(ui->rotX->value());
//    ui->glWidget->rotateY(ui->rotY->value());
//    ui->glWidget->rotateZ(ui->rotZ->value());
//    ui->glWidget->updateGL();
}

void MainWindow::on_ListaArquivos_currentTextChanged(const QString &currentText)
{
    cout<<"currentTextChanged = ("<<currentText.toStdString()<<")"<<endl;
    if (!currentText.isEmpty()) this->abrirArquivo(currentText);
}

void MainWindow::on_Update_clicked()
{
    if (!pasta.exists())
    {
        cout<<"* A pasta \""<<pasta.path().toStdString()<<"\" năo existe!"<<endl;
        return;
    }
    QStringList arquivos = listarArquivos();
    cout<<"* Pasta:\n"<<pasta.absolutePath().toStdString()<<endl;
    cout<<"* Arquivos:"<<endl;
    foreach(const QString& a,arquivos) cout<<a.toStdString()<<", ";
    cout<<endl<<endl;
    ui->ListaArquivos->clear();
    ui->ListaArquivos->addItems(arquivos);
}

void MainWindow::on_start_clicked()
{
    // Checar se a lista "glWidget->objects" tem algum objeto.
    // Espera-se que ela tenha pelo menos o conjunto de grupos de pontos.
    if (ui->glWidget->objects_quantidade() == 0)
    {
        cout<<"ERRO: a lista \"glWidget->objects\" deveria ter pelo menos um objeto."<<endl;
        return;
    }

    // Retirar da lista todos os objeto menos o 1ş:
    ui->glWidget->objects_SoPodeHaverUm();

    QList<Fecho> lista_fechos;
    switch(metodo_fecho)
    {
        case 0:
        {
            cout<<"\n**********"<<endl;
            cout<<"* Nenhum *"<<endl;
            cout<<"**********"<<endl;
            cout<<"(Nada a fazer aqui)"<<endl;
            break;
        }
        case 1:
        {
            cout<<"\n**********************"<<endl;
            cout<<"* A Marcha de Jarvis *"<<endl;
            cout<<"**********************"<<endl;
            pair<size_t,size_t> tempo;
            foreach(const Grupo& g,grupos_lidos)
            {
                Jarvis jar(g);
                lista_fechos.append(jar.convexhull());
                tempo = jar.contagemIteracoes();
                cout<<"*** Iteracoes: "<<tempo.first<<" de "<<tempo.second<<" ***"<<endl;
            }
            break;
        }
        case 2:
        {
            cout<<"\n*************************"<<endl;
            cout<<"* A Varredura de Graham *"<<endl;
            cout<<"*************************"<<endl;
            foreach(const Grupo& g,grupos_lidos)
            {
                Graham gra(g);
                gra.convexhull();
                ui->glWidget->addDrawble(new PoliPontos(gra.poligonoEstrelado));
            }
            break;
        }
        default:
        {
            cout<<"\n********"<<endl;
            cout<<"* ERRO *"<<endl;
            cout<<"********"<<endl;
            cout<<"Escolha de valor "<<metodo_fecho<<" năo definida!"<<endl;
            return;
        }
    }

    // Somente o Jarvis pode salvar os arquivos com o fecho:
    if (metodo_fecho == 1)
    {
        // Adicionar fecho a lista "glWidget->objects":
        ui->glWidget->addDrawble(new polifecho(this->grupos_lidos,lista_fechos));

        // Salvar lista no arquivo de saída:
        if (fh.salvar(lista_fechos)) cout<<"Arquivo de saida salvo com sucesso."<<endl;
        else cout<<"ERRO no salvamento do arquivo de saida!"<<endl;
    }

    ui->glWidget->updateGL();

    cout<<"glWidget.quantObjects: "<<ui->glWidget->objects_quantidade()<<endl;
}
